package com.sparrow.source.third;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sparrow.source.common.dto.FeiYouResponse;
import com.sparrow.source.common.dto.FeiYouUser;
import com.sparrow.source.common.dto.FeiYouUserItem;
import com.sparrow.source.common.dto.convert.IasUserConvert;
import com.sparrow.source.common.utils.SnowflakeIdGenerator;
import com.sparrow.source.persistense.FyUser;
import com.sparrow.source.service.IIasUserService;
import com.sparrow.source.third.service.IFeiYouUserService;
import com.sparrow.source.third.util.RestTemplateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * 飞友系统接口调用
 *
 * @author bryceyung
 * @since 2024/11/16
 */
@Component
@Slf4j
public class FeiYouClient {

    @Autowired
    private RestTemplateUtils restTemplateUtils;

    @Autowired
    private IFeiYouUserService feiYouUserService;

    @Autowired
    private IIasUserService iasUserService;

    @Autowired
    private IasUserConvert iasUserConvert;

    private final SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(1, 1);

    @Value("${third.feiyou.http.prefix}")
    private String url;

    @Value("${third.feiyou.appid}")
    private String appid;

    @Value("${third.feiyou.appsecret}")
    private String appSecret;

    @Autowired
    private Executor threadPoolTaskExecutor;

    /**
     * 用户初始化 分页获取
     *
     * @return
     */
    public FeiYouResponse userInit(Integer page) {
        Map<String, Object> paramMap = Collections.singletonMap("page", page);
        ResponseEntity<FeiYouResponse> responseEntity = null;
        try {
            HttpEntity request = new HttpEntity(paramMap, buildHeader(paramMap));
            responseEntity = restTemplateUtils.post(url + "user/init", request, FeiYouResponse.class);
        } catch (IllegalAccessException e) {
            log.error("FeiYouClient userInit error:{}", e.getCause());
        }
        log.info("userInit response:{}", responseEntity.getBody());
        return responseEntity.getBody();
    }

    /**
     * 获取全部人员信息
     *
     * @return
     */
    public FeiYouResponse getAllUserData() {
        FeiYouResponse response = userInit(1);
        FeiYouUser user = JSONObject.parseObject(JSONObject.toJSONString(response.getData()), FeiYouUser.class);
        List<FeiYouUserItem> totalList = user.getData();
        double totalPage = Math.ceil((double) user.getCount() / user.getLimit());
        for (int page = 2; page <= totalPage; page++) {
            FeiYouResponse forResp = userInit(page);
            FeiYouUser forUser = JSONObject.parseObject(JSONObject.toJSONString(forResp.getData()), FeiYouUser.class);
            totalList.addAll(forUser.getData());
        }
        user.setData(totalList);
        //同步至数据库
        List<FyUser> userList = JSONArray.parseArray(JSONArray.toJSONString(totalList), FyUser.class);
        feiYouUserService.saveOrUpdateBatch(userList);
        //添加到iasUser
        threadPoolTaskExecutor.execute(() -> {
            iasUserService.saveOrUpdateBatchByUid(iasUserConvert.convertIasUserBatch(userList));
        });
        response.setData(user);
        return response;
    }

    /**
     * 用户增量数据
     *
     * @return
     */
    public FeiYouResponse userIncrementingData() {
        Map<String, Object> paramMap = new LinkedHashMap<>();
        paramMap.put("page", 1);
        paramMap.put("time", System.currentTimeMillis() / 1000);
        ResponseEntity<FeiYouResponse> responseEntity = null;
        try {
            HttpEntity request = new HttpEntity(paramMap, buildHeader(paramMap));
            responseEntity = restTemplateUtils.post(url + "user/list", request, FeiYouResponse.class);
        } catch (IllegalAccessException e) {
            log.error("FeiYouClient userIncrementingData error:{}", e.getCause());
        }
        return responseEntity.getBody();
    }

    /**
     * 查询用户当日是否当班
     *
     * @param uid
     * @return
     */
    public FeiYouResponse isOnDuty(String uid) {
        Map<String, Object> paramMap = Collections.singletonMap("uid", uid);
        ResponseEntity<FeiYouResponse> responseEntity = null;
        try {
            HttpEntity request = new HttpEntity(paramMap, buildHeader(paramMap));
            responseEntity = restTemplateUtils.post(url + "user/duty", request, FeiYouResponse.class);
        } catch (IllegalAccessException e) {
            log.error("FeiYouClient isOnDuty error:{}", e.getCause());
        }
        return responseEntity.getBody();
    }

    /**
     * 组装请求头
     *
     * @return
     */
    public HttpHeaders buildHeader(Map<String, Object> obj) throws IllegalAccessException {
        HttpHeaders headers = new HttpHeaders();
        Long currentTime = System.currentTimeMillis() / 1000;
        Long nonce = snowflakeIdGenerator.nextId();
        StringBuffer buffer = new StringBuffer();
        buffer.append("SCHEDULE-APPID=").append(appid).append("&SCHEDULE-NONCE=").append(nonce)
                .append("&SCHEDULE-TIMESTAMP=").append(currentTime).append("&");
        buffer.append(traverseObjectProperties(obj));
        log.info("buildHeader SIGNATURE buffer:{}", buffer);
        headers.set("SCHEDULE-APPID", appid);
        headers.set("SCHEDULE-TIMESTAMP", String.valueOf(currentTime));
        headers.set("SCHEDULE-NONCE", String.valueOf(nonce));
        headers.set("SCHEDULE-SIGNATURE", new HmacUtils(HmacAlgorithms.HMAC_SHA_256, appSecret).hmacHex(buffer.toString()));
        return headers;
    }

    public static String traverseObjectProperties(Map<String, Object> obj) throws IllegalAccessException {
        StringBuffer result = new StringBuffer();
        obj.forEach((k, v) -> {
            result.append(k).append("=").append(v).append("&");
        });
        result.deleteCharAt(result.length() - 1);
        return result.toString();
    }
}
